package bid

import (
	"context"
	"gitee.com/alex_li/amazon-rpt/cmd/rpt/process/common"
	"gitee.com/alex_li/amazon-rpt/internal/db"
	"gitee.com/alex_li/amazon-rpt/internal/sdk/advertising"
	"github.com/lishimeng/app-starter"
	"github.com/lishimeng/app-starter/persistence"
	"github.com/lishimeng/go-log"
	"strconv"
	"time"
)

func UpdateKeywords(ctx context.Context) {
	startTime := time.Now()
	log.Info("start update keywords")
	common.TravelAmazonClients(ctx, updateKeywordOrg)
	endTime := time.Now()
	cost := endTime.Sub(startTime)
	log.Info("update total sp keyword done, [%f seconds]", cost.Seconds())
}

func updateKeywordOrg(ctx context.Context, lwa db.AmazonLwaCommon, handler *advertising.Client) {

	startTime := time.Now()
	doBatchBidAdjust(ctx, "sp", handler)
	doBatchBidAdjust(ctx, "sb", handler)
	endTime := time.Now()
	cost := endTime.Sub(startTime)
	log.Info("update sp keyword done, [org:%s][%f seconds]", lwa.Name, cost.Seconds())
}

type KeywordAdjust struct {
	CampaignId string
	AdGroupId  string
	KeywordId  string
	Bid        float64
	BidAdjust  float64
}

func doBatchBidAdjust(ctx context.Context, category string, handler *advertising.Client) {
	select {
	case <-ctx.Done():
		return
	default:
	}
	var list []db.BatchUpdateKeyword
	err := app.GetOrm().Transaction(func(tx persistence.TxContext) (e error) {
		_, e = tx.Context.QueryTable(new(db.BatchUpdateKeyword)).
			Filter("Category", category).
			Limit(10).
			All(&list)
		if e != nil {
			return
		}
		var adjustList []KeywordAdjust
		for _, item := range list {
			log.Info(item.KeywordId, item.BidAdjust)
			var a = KeywordAdjust{
				KeywordId: item.KeywordId,
				BidAdjust: item.BidAdjust,
			}

			var keywordCurrentState db.AmazonKeyword
			keywordCurrentState, e = getKeyword(tx, item.KeywordId, category)
			if e != nil {
				return
			}
			if len(keywordCurrentState.Category) == 0 {
				continue
			}
			a.Bid = keywordCurrentState.Bid
			a.CampaignId = keywordCurrentState.CampaignId
			a.AdGroupId = keywordCurrentState.AdGroupId
			adjustList = append(adjustList, a)
		}
		updateKeyword(handler, category, adjustList)
		removeKeywordUpdateJob(tx, list)
		return
	})
	if err != nil {
		log.Info(err)
	}
}

func updateKeyword(handler *advertising.Client, category string, list []KeywordAdjust) {
	switch category {
	case "sp":
		doUpdateSp(handler, list)
	case "sb":
		doUpdateSb(handler, list)
	}
}

func doUpdateSp(handler *advertising.Client, list []KeywordAdjust) {
	var req = advertising.KeywordUpdateReq{}
	for _, item := range list {
		req.Keywords = append(req.Keywords, advertising.KeywordUpdateItem{
			KeywordId: item.KeywordId,
			State:     "ENABLED",
			Bid:       item.Bid + item.BidAdjust,
		})
	}

	resp := handler.UpdateSpKeyword(req)
	log.Info(resp)
}

func doUpdateSb(handler *advertising.Client, list []KeywordAdjust) {
	var req = advertising.KeywordUpdateV3Req{}
	for _, item := range list {
		parseInt, _ := strconv.ParseInt(item.KeywordId, 32, 32)
		parseInt1, _ := strconv.ParseInt(item.AdGroupId, 32, 32)
		parseInt2, _ := strconv.ParseInt(item.CampaignId, 32, 32)
		req.Keywords = append(req.Keywords, advertising.KeywordUpdateItemV3{
			CampaignId: parseInt2,
			AdGroupId:  parseInt1,
			KeywordId:  parseInt,
			State:      "enable",
			Bid:        item.Bid + item.BidAdjust,
		})
	}

	resp := handler.UpdateSbKeyword(req)
	log.Info(resp)
}

func getKeyword(tx persistence.TxContext, id string, category string) (item db.AmazonKeyword, err error) {
	var list []db.AmazonKeyword
	_, err = tx.Context.QueryTable(new(db.AmazonKeyword)).
		Filter("KeywordId", id).
		Filter("Category", category).
		All(&list)
	if err != nil {
		log.Info(err)
	}
	if len(list) > 0 {
		item = list[0]
	}
	return
}

func removeKeywordUpdateJob(tx persistence.TxContext, list []db.BatchUpdateKeyword) {
	for _, item := range list {
		log.Info("remove keyword adjust: %s", item.KeywordId)
		break
		_, e := tx.Context.Delete(&item)
		if e != nil {
			log.Info(e)
		}
	}
}
